using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;


namespace Platformer
{
    public class PlatformerGame : Game
    {
        #region Declarations
        // System
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        // Game properties
        public enum GameState
        {
            Menu,
            Ingame,
            Pause
        }
        public GameState gameState = GameState.Menu;

        public int Level
        {
            get { return level; }
            set { level = value; }
        }
        int level = 1;

        // Constants
        public const int WIDTH = 1200, HEIGHT = 800;

        // Fonts
        public static SpriteFont debugFont;

        // Game components
        Menu menu;
        Parser parser;
        public Background Background
        {
            get { return background; }
            set { background = value; }
        }
        Background background;

        // Game elements
        public Character Player
        {
            get { return player; }
            set { Player = value; }
        }
        Character player;

        public List<Block> BlocksList
        {
            get { return blocksList; }
            set { blocksList = value; }
        }
        List<Block> blocksList = new List<Block>();

        FadeManager lol;
        #endregion

        public PlatformerGame()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            graphics.PreferredBackBufferWidth = WIDTH;
            graphics.PreferredBackBufferHeight = HEIGHT;

            IsMouseVisible = false;
            MediaPlayer.Volume = 0.05f;
        }

        protected override void Initialize()
        {
            lol = new FadeManager(20, 20, this);
            player = new Character(this);
            menu = new Menu(this);
            parser = new Parser(this);
            background = new Background(this);
            parser.CreateMap(1);
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(graphics.GraphicsDevice);

            menu.LoadContent();
            debugFont = Content.Load<SpriteFont>("Fonts/debug");
        }
        protected override void UnloadContent()
        {

        }

        protected override void Update(GameTime gameTime)
        {

            if (gameState == GameState.Ingame)
            {
                player.Update();

                foreach (Block item in blocksList)
                    item.Update();
            }
            menu.Update();
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
            spriteBatch.Begin();
            menu.Draw(spriteBatch);

            if (gameState == GameState.Ingame || gameState == GameState.Pause)
            {
                background.Draw(spriteBatch);
                foreach (Block item in blocksList)
                    item.Draw(spriteBatch);
                player.Draw(spriteBatch);
            }
            spriteBatch.End();
            base.Draw(gameTime);
        }

        // Custom
        void TurnBlack()
        {

        }

    }

    public class FadeRect
    {
        Texture2D texture;
        int width, height;
        public int Opacity
        {
            get { return opacity; }
            set { opacity = value; }
        }
        int opacity = 255;

        public bool Hidden
        {
            get { return hidden; }
            set { hidden = value; }
        }
        bool hidden = false;
        Point pos;

        public FadeRect(int width, int height, Point pos, ContentManager Content)
        {
            this.pos = pos;
            this.width = width;
            this.height = height;
            texture = Content.Load<Texture2D>("Misc/pixel");
        }

        public void Update()
        {

        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(texture, new Rectangle(pos.X * width, pos.Y * height, width, height), new Color(0, 0, 0, opacity));
        }
    }

    public class FadeManager
    {
        int xCount, yCount;
        PlatformerGame game;
        Texture2D texture;
        int width, height;
        FadeRect[,] tab;
        Random rand = new Random();

        int _x = 0, _y = 0;

        public FadeManager(int xCount, int yCount, PlatformerGame game)
        {
            this.xCount = xCount;
            this.yCount = yCount;
            this.game = game;
            texture = game.Content.Load<Texture2D>("Misc/pixel");
            tab = new FadeRect[xCount, yCount];

            width = PlatformerGame.WIDTH / xCount;
            height = PlatformerGame.HEIGHT / yCount;

            Initialize();
        }

        void Initialize()
        {
            for (int y = 0; y < yCount; y++)
            {
                for (int x = 0; x < xCount; x++)
                {
                    FadeRect temp = new FadeRect(width, height, new Point(x, y), game.Content);
                    tab[x, y] = temp;
                }
            }
        }

        public void Update()
        {
            tab[_x, _y].Opacity = 0;
            if (_x == xCount - 1)
            {
                _x = 0;
                _y++;
            }
            else
                _x++;
            
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            foreach (FadeRect item in tab)
                item.Draw(spriteBatch);

            spriteBatch.DrawString(PlatformerGame.debugFont, "" + _x, new Vector2(0, 0), Color.Red);
            spriteBatch.DrawString(PlatformerGame.debugFont, "" + _y, new Vector2(0, 20), Color.Red);
            spriteBatch.DrawString(PlatformerGame.debugFont, "" + xCount, new Vector2(0, 40), Color.Red);
        }
    }

    // Entry point
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main(string[] args)
        {
            using (PlatformerGame game = new PlatformerGame())
            {
                game.Run();
            }
        }
    }
}
